local jass = require 'jass.common'
local code = require 'jass.code'
local dbg  = require 'jass.debug'
local symbols  = require 'symbol.rect'

local rect = {}
setmetatable(rect,rect)
ac.rect = rect 

-- 存放编辑器生成的预设区域
rect.rects = {}


-- 输出区域
function rect:__tostring()
	return ('rect(%.02f,%.02f,%.02f,%.02f)'):format(self:get())
end

--- 创建矩形区域
--- 可以使用的参数 
--- 1: center,width,height
--- 2: minx,miny,maxx,maxy
function rect:__call(...)
    local n = select('#',...)
    if n == 4 then 
        return rect.create(...)
    elseif n == 3 then 
        return rect.from(...)
    elseif n == 1 then 
        return rect.globals(...)
    end
end

--- 获取区域的宽度和高度 2D
function rect:__unm()
    local minx,miny,maxx,maxy = self:get()
    return maxx-minx,maxy-miny
end 

--- 获得一个临时的jass区域
function rect.j_temp(rct)
	jass.SetRect(rect.handle, rct:get())
	return rect.handle
end

--- 创建矩形区域
function rect.create(minx, miny, maxx, maxy)
	return setmetatable({minx = minx, miny = miny, maxx = maxx, maxy = maxy}, rect)
end

--- 获取预设区域
function rect.j_rect(name)
    return rect.globals(name)
end
function rect.globals(name)
    if not rect.rects[name] then 
        -- log.info('读取不存在的预设区域',name)
    end 
    return rect.rects[name]
end

--- 根据中心点,宽,高创建矩形区域
function rect.from(center,width,height)
    local x,y = center:get_point():get()
	local minx = x - width / 2
	local miny = y - height / 2 
	local maxx = x + width / 2 
	local maxy = y + height / 2
	return rect.create(minx, miny, maxx, maxy)
end 

--- 扩展矩形区域
function rect:__add(dest)
	local minx0, miny0, maxx0, maxy0 = self:get()
	local minx1, miny1, maxx1, maxy1 = table.unpack(dest)
	return rect.create(minx0 + minx1, miny0 + miny1, maxx0 + maxx1, maxy0 + maxy1)
end

--- 初始化模块
function rect.init()

    rect.map = rect(
		jass.GetCameraBoundMinX() - jass.GetCameraMargin(jass.CAMERA_MARGIN_LEFT) ,
		jass.GetCameraBoundMinY() - jass.GetCameraMargin(jass.CAMERA_MARGIN_BOTTOM) ,
		jass.GetCameraBoundMaxX() + jass.GetCameraMargin(jass.CAMERA_MARGIN_RIGHT) ,
		jass.GetCameraBoundMaxY() + jass.GetCameraMargin(jass.CAMERA_MARGIN_TOP) 
	)

    rect.handle = jass.Rect(0, 0, 0, 0)
    dbg.handle_ref(rect.handle)

    for i, data in ipairs(symbols) do 
        rect.rects[data.name] = rect.create( data.minx, data.miny, data.maxx, data.maxy )
    end 
end 

-- 结构
local mt = {}
rect.__index = mt 

--类型
mt.type = 'rect'

--4个数值
mt.minx = 0
mt.miny = 0
mt.maxx = 0
mt.maxy = 0

-- 锚点获取
rect.anchors = {
    ['左上'] = function(self)
        return ac.point(self.minx, self.maxy)
    end,

    ['上'] = function(self)
        return ac.point((self.minx + self.maxx) / 2, self.maxy)
    end,

    ['右上'] = function(self)
        return ac.point(self.maxx, self.maxy)
    end,
    
    ['右'] = function(self)
        return ac.point(self.maxx, (self.miny + self.maxy) / 2)
    end,
        
    ['右下'] = function(self)
        return ac.point(self.maxx, self.miny)
    end,
            
    ['下'] = function(self)
        return ac.point((self.minx + self.maxx) / 2, self.miny)
    end,
                
    ['左下'] = function(self)
        return ac.point(self.minx, self.miny)
    end,
                    
    ['左'] = function(self)
        return ac.point(self.minx, (self.miny + self.maxy) / 2)
    end,
                        
    ['中心'] = function(self)
        return ac.point((self.minx + self.maxx) / 2, (self.miny + self.maxy) / 2)
    end,
}

--- 获取锚点
function mt:get_anchor(name)
    if name and rect.anchors[name] then 
        return rect.anchors[name](self)
    end 
    return self:center()
end

--- 获取四个角
function mt:get_corner()
    return self:get_anchor('左上'),
    self:get_anchor('右上'),
    self:get_anchor('左下'),
    self:get_anchor('右下')
end 

--- 获取4个值
function mt:get()
	return self.minx, self.miny, self.maxx, self.maxy
end

--- 获取中心点
function mt:center()
	return rect.anchors['中心'](self) 
end

--- 物体是否在区域内
function mt:has(dest)
	local x,y = dest:get_point():get()
	return self.minx <= x and x <= self.maxx and self.miny <= y and y <= self.maxy
end

--- 获取区域内随机点
function mt:random()
	return ac.point(math.random(self.minx,self.maxx), math.random(self.miny,self.maxy))
end 
function mt:get_random_point()
    return self:random()
end

--- 获取区域位置
function mt:get_point()
    return self:center()
end

--- 获取区域高度
function mt:get_height()
    return self:center():get_height()
end 

--- 保存为预设区域
function mt:save(name)
    rect.rects[name] = self
end 

return rect